import java.awt.Color;
import java.awt.Dimension;

/**
 * Jordan Lange
 */
public class TetrisGrid {
    private static final int BOX_SIZE = 20;
    private int[][] grid;

    public TetrisGrid(int x, int y) {
        if (x < 0 || y < 0) {
            throw new IllegalArgumentException("Invalid grid size");
        }
        grid = new int[x][y];
    }

    public Dimension getGridSize() {
        return new Dimension(grid.length, grid[0].length);
    }

    public Dimension getGridConstraints() {
        return new Dimension(grid.length * BOX_SIZE, grid[0].length * BOX_SIZE);
    }

    public static int getBoxSize() {
        return BOX_SIZE;
    }

    public Color colorAt(int x, int y) {
        return new Color(grid[x][y]);
    }

    public void addPiece(Piece p) {
        int[][] constraint = p.getCurrentConstraint();
        int startX = p.getContainer().x;
        int startY = p.getContainer().y;
        for (int i = 0; i < constraint.length; i++) {
            for (int x = 0; x < constraint[i].length; x++) {
                if (constraint[i][x] == 0) {
                    grid[startX + i][startY + x] = p.getType().getColor().getRGB();
                }
            }
        }
    }

    public void removePiece(Piece p) {
        int[][] constraint = p.getCurrentConstraint();
        int startX = p.getContainer().x;
        int startY = p.getContainer().y;
        for (int i = 0; i < constraint.length; i++) {
            for (int x = 0; x < constraint[i].length; x++) {
                if (constraint[i][x] != -1) {
                    grid[startX + i][startY + x] = 0;
                }
            }
        }
    }

    // checks to see if a piece p, that has the move in question applied before
    // calling this method, is valid
    public boolean isValid(Piece p) {
        int height = p.getContainer().height;
        int width = p.getContainer().width;

        // If the bottom goes off the grid, or the right/left side goes off the grid it's invalid
        if ((p.getContainer().x - 1) + width >= grid.length || p.getContainer().x < 0 ||
                (p.getContainer().y - 1) + height >= grid[0].length) {
            return false;
        }
        // check the bounds of the piece to see if the move location has any colors that
        // would conflict with the piece
        int[][] constr = p.getCurrentConstraint();
        for (int x = width; x > 0; x--) {
            for (int y = height; y > 0; y--) {
                if (constr[x - 1][y - 1] != -1 && // If the piece occupies this space...
                        grid[(p.getContainer().x - 1) + x][(p.getContainer().y - 1) + y] != 0) {
                    return false;
                }
            }
        }
        return true;
    }

    public int getUnbrokenRow() {
        boolean unbroken = true;
        int row = 0;
        for (int col = 0; col < grid.length; col++) {
            if (row >= grid[col].length) {
                break;
            }
            if (grid[col][row] != 0) {
                unbroken = true;
            } else {
                col = -1;
                row++;
                unbroken = false;
            }
        }
        if (unbroken) {
            return row;
        } else {
            return -1;
        }
    }

    public void removeRow(int row) {
        if (row < 0 || row >= grid[0].length) {
            throw new IllegalArgumentException("Non-existant row");
        }
        for (int col = 0; col < grid.length; col++) {
            grid[col][row] = 0;
        }
        // move all rows above it down 1
        for (int col = 0; col < grid.length; col++) {
            for (int i = row; i > 0; i--) {
                grid[col][i] = grid[col][i - 1];
            }
        }
    }

    // garbage collection will free the memory used by the old grid
    public void reset() {
        grid = new int[grid.length][grid[0].length];
    }
}
